#include "common.h"
#include "gpio.h"

volatile struct GPIO_MemMap *GPIOx[5]=GPIO_BASE_PTRS;
volatile struct PORT_MemMap *PORTx[5]=PORT_BASE_PTRS;

int gpio_init(int port, int channel, int io, int value){
    if(port<0||port>4
     ||channel<0||channel>31
     ||io<0||io>1
     ||(io==1&&(value<0||value>1)))
        return -1;

    /* Enable the GPIO function on the PIN */
    PORT_PCR_REG(PORTx[port], channel)=PORT_PCR_MUX(1);

    switch(io){
        case GPIO_GPI:
            GPIO_PDDR_REG(GPIOx[port])&=~(1<<channel); // set PIN as input
            break;
        case GPIO_GPO:
            GPIO_PDDR_REG(GPIOx[port])|=(1<<channel); // set PIN as output
            if(value==0)
                GPIO_PSOR_REG(GPIOx[port])|=(1<<channel); // set PIN output as 0
            else
                GPIO_PCOR_REG(GPIOx[port])|=(1<<channel); // set PIN output as 1
    }

    return 0;
}

void gpio_toggle(int port, int channel){
    GPIO_PTOR_REG(GPIOx[port])=(1<<channel);
}

void gpio_set(int port, int channel, int value){
    /* check the PIN is set to GPIO function */
    if(value)
        GPIO_PCOR_REG(GPIOx[port])=(1<<channel); // set PIN as 0
    else
        GPIO_PSOR_REG(GPIOx[port])=(1<<channel); // set PIN as 1
}

int gpio_read(int port, int channel){
    int var;
    var=GPIO_PDIR_REG(GPIOx[port]);
    if(var&(1<<channel))
        return 1;
    return 0;
}
